{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "创建一个示例的LCEL"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "b9fdf8e6c8a122d1"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "from langchain_core.runnables import RunnablePassthrough\n",
    "from langchain_community.embeddings import DashScopeEmbeddings\n",
    "from langchain_community.vectorstores import FAISS\n",
    "from langchain_core.output_parsers import StrOutputParser\n",
    "import os\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "load_dotenv()\n",
    "\n",
    "vectorstore = FAISS.from_texts(\n",
    "    [\"harrison worked at kensho\"], embedding=DashScopeEmbeddings(\n",
    "        dashscope_api_key=os.getenv(\"DASHSCOPE_API_KEY\"), model=\"text-embedding-v1\"\n",
    "    )\n",
    ")\n",
    "retriever = vectorstore.as_retriever()\n",
    "\n",
    "template = \"\"\"Answer the question based only on the following context:\n",
    "{context}\n",
    "\n",
    "Question: {question}\n",
    "\"\"\"\n",
    "\n",
    "prompt = ChatPromptTemplate.from_template(template)\n",
    "# 请注意，我们将max_retries = 0设置为避免在RateLimits等情况下重试\n",
    "llm = ChatOpenAI(\n",
    "    # 若没有配置环境变量，请用百炼API Key将下行替换为：api_key=\"sk-xxx\",\n",
    "    openai_api_key=os.getenv(\"DASHSCOPE_API_KEY\"),\n",
    "    openai_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n",
    "    model_name=\"qwen-max\",\n",
    "    temperature=0.0,\n",
    "    max_retries=0,\n",
    ")\n",
    "chain = {\"context\":retriever,\"question\":RunnablePassthrough()} | prompt | llm | StrOutputParser()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-10-28T09:16:01.850008Z",
     "start_time": "2024-10-28T09:15:59.203343Z"
    }
   },
   "id": "2624c79034bd41c4",
   "execution_count": 1
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 获取图形\n",
    "获取可运行对象的图形"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "f47fa600800acddf"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "Graph(nodes={'452a0b2663604935a36271133afcb84b': Node(id='452a0b2663604935a36271133afcb84b', name='Parallel<context,question>Input', data=<class 'langchain_core.runnables.base.RunnableParallel<context,question>Input'>, metadata=None), 'a5513131bd8a497fa2100182b6790bda': Node(id='a5513131bd8a497fa2100182b6790bda', name='Parallel<context,question>Output', data=<class 'langchain_core.utils.pydantic.RunnableParallel<context,question>Output'>, metadata=None), 'ba11585da9114b558ea8fadb7bb34b70': Node(id='ba11585da9114b558ea8fadb7bb34b70', name='VectorStoreRetriever', data=VectorStoreRetriever(tags=['FAISS', 'DashScopeEmbeddings'], vectorstore=<langchain_community.vectorstores.faiss.FAISS object at 0x11fc717c0>, search_kwargs={}), metadata=None), 'b9b01488e31a44508581c0995c4ff9e9': Node(id='b9b01488e31a44508581c0995c4ff9e9', name='Passthrough', data=RunnablePassthrough(), metadata=None), '062816ed7cf34cdcbf28da635c054746': Node(id='062816ed7cf34cdcbf28da635c054746', name='ChatPromptTemplate', data=ChatPromptTemplate(input_variables=['context', 'question'], input_types={}, partial_variables={}, messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['context', 'question'], input_types={}, partial_variables={}, template='Answer the question based only on the following context:\\n{context}\\n\\nQuestion: {question}\\n'), additional_kwargs={})]), metadata=None), '51c27a4d838d481d9b6871525a978442': Node(id='51c27a4d838d481d9b6871525a978442', name='ChatOpenAI', data=ChatOpenAI(client=<openai.resources.chat.completions.Completions object at 0x11fc9cf50>, async_client=<openai.resources.chat.completions.AsyncCompletions object at 0x11fc9ecc0>, root_client=<openai.OpenAI object at 0x11532e180>, root_async_client=<openai.AsyncOpenAI object at 0x11fc9cfb0>, model_name='qwen-max', temperature=0.0, model_kwargs={}, openai_api_key=SecretStr('**********'), openai_api_base='https://dashscope.aliyuncs.com/compatible-mode/v1', max_retries=0), metadata=None), 'd8a34e325c9a4d8096f5f5ed9d6d5b8f': Node(id='d8a34e325c9a4d8096f5f5ed9d6d5b8f', name='StrOutputParser', data=StrOutputParser(), metadata=None), '763e0a3eee304121ba0597663af927dd': Node(id='763e0a3eee304121ba0597663af927dd', name='StrOutputParserOutput', data=<class 'langchain_core.output_parsers.string.StrOutputParserOutput'>, metadata=None)}, edges=[Edge(source='452a0b2663604935a36271133afcb84b', target='ba11585da9114b558ea8fadb7bb34b70', data=None, conditional=False), Edge(source='ba11585da9114b558ea8fadb7bb34b70', target='a5513131bd8a497fa2100182b6790bda', data=None, conditional=False), Edge(source='452a0b2663604935a36271133afcb84b', target='b9b01488e31a44508581c0995c4ff9e9', data=None, conditional=False), Edge(source='b9b01488e31a44508581c0995c4ff9e9', target='a5513131bd8a497fa2100182b6790bda', data=None, conditional=False), Edge(source='a5513131bd8a497fa2100182b6790bda', target='062816ed7cf34cdcbf28da635c054746', data=None, conditional=False), Edge(source='062816ed7cf34cdcbf28da635c054746', target='51c27a4d838d481d9b6871525a978442', data=None, conditional=False), Edge(source='d8a34e325c9a4d8096f5f5ed9d6d5b8f', target='763e0a3eee304121ba0597663af927dd', data=None, conditional=False), Edge(source='51c27a4d838d481d9b6871525a978442', target='d8a34e325c9a4d8096f5f5ed9d6d5b8f', data=None, conditional=False)])"
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.get_graph()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-10-28T09:16:36.616856Z",
     "start_time": "2024-10-28T09:16:36.547291Z"
    }
   },
   "id": "f445064a5d17176d",
   "execution_count": 2
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 打印图形\n",
    "为了更好理解，打印可运行对象的图形。安装依赖`poetry add grandalf` "
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "53e3dcbca901d53e"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           +---------------------------------+         \n",
      "           | Parallel<context,question>Input |         \n",
      "           +---------------------------------+         \n",
      "                    **               **                \n",
      "                 ***                   ***             \n",
      "               **                         **           \n",
      "+----------------------+              +-------------+  \n",
      "| VectorStoreRetriever |              | Passthrough |  \n",
      "+----------------------+              +-------------+  \n",
      "                    **               **                \n",
      "                      ***         ***                  \n",
      "                         **     **                     \n",
      "           +----------------------------------+        \n",
      "           | Parallel<context,question>Output |        \n",
      "           +----------------------------------+        \n",
      "                             *                         \n",
      "                             *                         \n",
      "                             *                         \n",
      "                  +--------------------+               \n",
      "                  | ChatPromptTemplate |               \n",
      "                  +--------------------+               \n",
      "                             *                         \n",
      "                             *                         \n",
      "                             *                         \n",
      "                      +------------+                   \n",
      "                      | ChatOpenAI |                   \n",
      "                      +------------+                   \n",
      "                             *                         \n",
      "                             *                         \n",
      "                             *                         \n",
      "                   +-----------------+                 \n",
      "                   | StrOutputParser |                 \n",
      "                   +-----------------+                 \n",
      "                             *                         \n",
      "                             *                         \n",
      "                             *                         \n",
      "                +-----------------------+              \n",
      "                | StrOutputParserOutput |              \n",
      "                +-----------------------+              \n"
     ]
    }
   ],
   "source": [
    "chain.get_graph().print_ascii()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-10-28T09:18:34.064334Z",
     "start_time": "2024-10-28T09:18:34.009626Z"
    }
   },
   "id": "4f12b16469ebda31",
   "execution_count": 4
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 获取提示\n",
    "每个链的一个重要部分是使用的提示。您可以获取链中存在的提示:\n"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "f4e71226c67d2d08"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "data": {
      "text/plain": "[ChatPromptTemplate(input_variables=['context', 'question'], input_types={}, partial_variables={}, messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['context', 'question'], input_types={}, partial_variables={}, template='Answer the question based only on the following context:\\n{context}\\n\\nQuestion: {question}\\n'), additional_kwargs={})])]"
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "chain.get_prompts()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-10-28T09:20:53.240640Z",
     "start_time": "2024-10-28T09:20:53.234090Z"
    }
   },
   "id": "9e05e74184be813d",
   "execution_count": 5
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "12aae24fb5fc417c"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
